package ldh.common.testui.util;

import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle;
import javafx.stage.Popup;
import javafx.stage.Window;

/**
 * Created by ldh on 2019/12/13.
 */
public class ReginMovable {

    private Region movablePane;
    private Rectangle moveTrackingRect;
    private Popup moveTrackingPopup;
    private double startMoveX = -1.0D;
    private double startMoveY = -1.0D;
    private Boolean dragging = Boolean.valueOf(false);

    public ReginMovable(Region movablePane) {
        this.movablePane = movablePane;
        this.buildMovable();
    }

    private void buildMovable() {
        if(this.movablePane != null) {
            this.movablePane.setOnMouseDragged((e) -> {
                this.moveWindow(e);
            });
            this.movablePane.setOnMouseReleased((e) -> {
                this.endMoveWindow(e);
            });
            this.movablePane.setOnDragDetected((e) -> {
                this.startMoveWindow(e);
            });
        }
    }

    public void startMoveWindow(MouseEvent evt) {
        if(evt.getX() >= 3.0D && evt.getX() <= this.movablePane.getScene().getWindow().getWidth() - 3.0D && evt.getY() <= this.movablePane.getScene().getWindow().getHeight() - 3.0D) {
            this.startMoveX = evt.getScreenX();
            this.startMoveY = evt.getScreenY();
            this.dragging = Boolean.valueOf(true);
            this.moveTrackingRect = new Rectangle();
            this.moveTrackingRect.setWidth(this.movablePane.getWidth());
            this.moveTrackingRect.setHeight(this.movablePane.getHeight());
            this.moveTrackingRect.setStyle("-fx-fill: #f3f3f4;\n    -fx-arc-height: 4;\n    -fx-arc-width: 4;-fx-opacity: 0.6");
            this.moveTrackingPopup = new Popup();
            this.moveTrackingPopup.getContent().add(this.moveTrackingRect);
            this.moveTrackingPopup.show(this.movablePane.getScene().getWindow());
            this.moveTrackingPopup.setOnHidden((e) -> {
                this.resetMoveOperation();
            });
        }
    }

    public void moveWindow(MouseEvent evt) {
        if(this.dragging.booleanValue()) {
            double endMoveX = evt.getScreenX();
            double endMoveY = evt.getScreenY();
            this.moveTrackingPopup.setX(movablePane.getScene().getWindow().getX() + movablePane.getLayoutX() + (endMoveX - startMoveX) + movablePane.sceneToLocal(0, 0).getX());
            this.moveTrackingPopup.setY(movablePane.getScene().getWindow().getX() + movablePane.getLayoutY() + (endMoveY - startMoveY) + movablePane.sceneToLocal(0, 0).getY());
        }

    }

    public void endMoveWindow(MouseEvent evt) {
        if(this.dragging.booleanValue()) {
            double endMoveX = evt.getScreenX();
            double endMoveY = evt.getScreenY();
            movablePane.setTranslateX(movablePane.getTranslateX() + (endMoveX - this.startMoveX));
            movablePane.setTranslateY(movablePane.getTranslateY() + (endMoveY - this.startMoveY));
            if(this.moveTrackingPopup != null) {
                this.moveTrackingPopup.hide();
                this.moveTrackingPopup = null;
            }
        }

        this.resetMoveOperation();
    }

    private void resetMoveOperation() {
        this.startMoveX = 0.0D;
        this.startMoveY = 0.0D;
        this.dragging = Boolean.valueOf(false);
        this.moveTrackingRect = null;
    }
}
